﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using HYCoordinate;

namespace SetPipe.Utiltiy
{
	public class PipeDrainMakerApplication
	{
		public static bool UseMessageTag
		{
			get
			{
				return PipeDrainMakerApplication.useMessageTag;
			}
			set
			{
				PipeDrainMakerApplication.useMessageTag = value;
			}
		}

		public PipeDrainMakerApplication(UIApplication ui_app, Autodesk.Revit.DB.Document m_doc)
		{
			this.ui_app = ui_app;
			this.m_doc = m_doc;
			this.thisStack = new InputDataStack(m_doc);
			this.outPutFamilyFilePath.Clear();
		}

		public void AddOnePoint(OnePipeInputDataPacker input)
		{
			if (input != null)
			{
				this.thisStack.AddOnePoint(input);
				return;
			}
			this.thisStack.SetEnd(true);
		}

		public XYZ GetEndPointNow()
		{
			return this.thisStack.GetEndPoint();
		}

		public void ResetEndPointNow()
		{
			this.thisStack = new InputDataStack(this.m_doc);
		}

		public void MakeFamilies(ProcessBarForm tempForm)
		{
			FamilyCreater familyCreater = FamilyCreater.GetFamilyCreater();
			List<ThreePipeInputDataPacker> result = this.thisStack.GetResult();
			int num = 0;
			tempForm.SetText(StaticRescource.StrMessage_NowCreatingFamily);
			tempForm.SetProcessBarMax(result.Count - 1);
			tempForm.SetProcessBarNowValue(0);
			for (int i = 0; i < result.Count; i++)
			{
				List<XYZ> list = new List<XYZ>();
				List<XYZ> list2 = new List<XYZ>();
				list = result[i].lstRectPoints;
				list2.Add(Utiltiy.GetMidPoint(list[0], list[1]));
				if (i == result.Count - 1)
				{
					list2.Add(Utiltiy.GetMidPoint(list[4], list[5]));
				}
				tempForm.SetProcessBarNowValue(i);
				int num2 = 0;
				foreach (PipeBoundryCurvePakcer pipeBoundryCurvePakcer in result[i].GetLstBoundryCurvePacker())
				{
					double stemp = this.thisStack.lstOnePointInputData[num].GetPipeParameters(0)[PipeUseParameterEnum.DistanceFloor];
					num++;
					double etemp = this.thisStack.lstOnePointInputData[num].GetPipeParameters(0)[PipeUseParameterEnum.DistanceFloor];
					if (!this.useFamily(pipeBoundryCurvePakcer, stemp, etemp, list2[num2]))
					{
						this.outPutFamilyFilePath.Add(familyCreater.SetResultData(this.ui_app, pipeBoundryCurvePakcer, pipeBoundryCurvePakcer.Height));
						this.lstRealStartPoints.Add(familyCreater.GetRealStartPoint());
					}
					num2++;
				}
			}
			if (result.Count == 0 && this.thisStack.GetTwoInputDataPacker(0) != null)
			{
				double stemp = this.thisStack.lstOnePointInputData[0].GetPipeParameters(0)[PipeUseParameterEnum.DistanceFloor];
				double etemp = this.thisStack.lstOnePointInputData[1].GetPipeParameters(0)[PipeUseParameterEnum.DistanceFloor];
				TwoPipeInputDataPakcer twoInputDataPacker = this.thisStack.GetTwoInputDataPacker(0);
				double[] array = new double[]
				{
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.Width],
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.Height],
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.DistanceFloor],
					(double)twoInputDataPacker.GetFamilyFileIndex(0)
				};
				double[] valueParams = new double[]
				{
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.Width],
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.Height],
					twoInputDataPacker.GetPipeParameters(1)[PipeUseParameterEnum.DistanceFloor],
					(double)twoInputDataPacker.GetFamilyFileIndex(0)
				};
				List<XYZ> list3 = new List<XYZ>();
				List<XYZ> list4 = new List<XYZ>();
				PipeBoundryCurvePakcer input = new PipeBoundryCurvePakcer(twoInputDataPacker.GetPoint(0), twoInputDataPacker.GetPoint(1), Utiltiy.GetNormalLineBoundryCurves(twoInputDataPacker.GetPoint(0), twoInputDataPacker.GetPoint(1), twoInputDataPacker.GetPipeParameters(1), ref list3), false, valueParams);
				list4.Add(Utiltiy.GetMidPoint(list3[0], list3[1]));
				list4.Add(Utiltiy.GetMidPoint(list3[0], list3[1]));
				this.useFamily(input, stemp, etemp, list4[0]);
			}
			tempForm.SetProcessBarNowValue(result.Count - 1);
		}

		public void AddFamilies(ProcessBarForm tempForm)
		{
			new MyFamilyLoadOptions();
			int num = 0;
			Transaction transaction = new Transaction(this.m_doc, "addFamily");
			transaction.Start();
			tempForm.SetText(StaticRescource.StrMessage_NowLoadFamily);
			tempForm.SetProcessBarMax(this.outPutFamilyFilePath.Count - 1);
			tempForm.SetProcessBarNowValue(0);
			foreach (string text in this.outPutFamilyFilePath)
			{
				tempForm.SetProcessBarNowValue(num);
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				FamilySymbol familySymbol = null;
				this.m_doc.LoadFamilySymbol(text, fileNameWithoutExtension, out familySymbol);
				familySymbol.Activate();
				this.m_doc.Create.NewFamilyInstance(this.lstRealStartPoints[num], familySymbol, (Autodesk.Revit.DB.Structure.StructuralType)3);
				num++;
			}
			tempForm.SetProcessBarNowValue(this.outPutFamilyFilePath.Count - 1);
			transaction.Commit();
			Regex regex = new Regex("^" + StaticRescource.StrTempNameOfOutPut + ".*\\.rfa");
			foreach (FileInfo fileInfo in new DirectoryInfo(StaticRescource.StrPathOut).GetFiles())
			{
				if (regex.IsMatch(fileInfo.FullName))
				{
					File.Delete(fileInfo.FullName);
				}
			}
		}

		public void DeleteAllDetailCurves()
		{
			this.thisStack.DeleteAllDetailCurves();
		}

		private bool useFamily(PipeBoundryCurvePakcer input, double stemp, double etemp, XYZ xyz)
		{
			if (input.IfCorner)
			{
				return false;
			}
			Transaction transaction = new Transaction(this.m_doc, "addFamily");
			transaction.Start();
			string text = StaticRescource.StrArrayUsePipeFamilyNames[input.FamilyFileIndex];
			FamilySymbol familySymbol = null;
			if (!this.ifHasUseFamily(text, out familySymbol))
			{
				string text2 = StaticRescource.StrUsePipeFamilyPath + text + StaticRescource.StrRfa;
                this.m_doc.LoadFamilySymbol(text2, text, out familySymbol);
			}
			if (familySymbol != null)
			{
				familySymbol.Activate();
				FamilyInstance familyInstance = this.m_doc.Create.NewFamilyInstance(xyz, familySymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
				Parameter parameter = familyInstance.GetParametersByName(StaticRescource.StrLength)[0];
				double num = input.GetPoint(0).DistanceTo(input.GetPoint(1));
				parameter.Set(num);
				familyInstance.GetParametersByName(StaticRescource.StrWidth).Single<Parameter>().Set(input.Width);
				familyInstance.GetParametersByName(StaticRescource.StartHeight).Single<Parameter>().Set(input.Height);
				familyInstance.GetParametersByName(StaticRescource.EndHeight).Single<Parameter>().Set(input.Height);
				familyInstance.GetParametersByName(StaticRescource.StartDistanceFloor).Single<Parameter>().Set(stemp);
				familyInstance.GetParametersByName(StaticRescource.EndDistanceFloor).Single<Parameter>().Set(etemp);
				Line line = Line.CreateBound(input.GetPoint(0), input.GetPoint(1));
				Line line2 = Line.CreateUnbound(input.GetPoint(0), new XYZ(1.0, 0.0, 0.0));
				double num2;
				if (input.GetPoint(1).Y > input.GetPoint(0).Y)
				{
					num2 = line.Direction.AngleTo(line2.Direction);
				}
				else
				{
					num2 = line.Direction.AngleTo(line2.Direction);
					num2 = -num2;
				}
				Line line3 = Line.CreateUnbound(xyz, StaticRescource.GetXYPlaneNorme(0));
				ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, line3, num2);
			}
			transaction.Commit();
			return true;
		}

		private bool ifHasUseFamily(string familyName, out FamilySymbol outFamilySymobl)
		{
			outFamilySymobl = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.OfCategory(BuiltInCategory.OST_MassTags_Obsolete_IdInWrongRange).WhereElementIsElementType();
			foreach (Element element in (filteredElementCollector.ToElements() as List<Element>))
			{
				FamilySymbol familySymbol = element as FamilySymbol;
				if (familySymbol.Family.Name == familyName)
				{
					outFamilySymobl = familySymbol;
					return true;
				}
			}
			if (outFamilySymobl == null)
			{
				TaskDialog.Show("盈建科提示", "读取族失败");
			}
			outFamilySymobl.Activate();
			return true;
		}

		private Document m_doc;

		private static UIDocument UIdoc;

		private static bool useMessageTag = true;

		private UIApplication ui_app;

		private InputDataStack thisStack;

		private List<string> outPutFamilyFilePath = new List<string>();

		private List<XYZ> lstRealStartPoints = new List<XYZ>();
	}
}
